<template>
  <div class="unified-markdown-editor">
    <!-- 编辑器头部 -->
    <div class="editor-header">
      <div class="editor-tabs">
        <el-radio-group v-model="activeTab" size="small">
          <el-radio-button value="edit">编辑</el-radio-button>
          <el-radio-button value="preview">预览</el-radio-button>
          <el-radio-button value="split">分屏</el-radio-button>
        </el-radio-group>
      </div>
      
      <div class="editor-actions">
        <el-button-group size="small">
          <el-button @click="insertBold" title="粗体 (Ctrl+B)">
            <strong>B</strong>
          </el-button>
          <el-button @click="insertItalic" title="斜体 (Ctrl+I)">
            <em>I</em>
          </el-button>
          <el-button @click="insertLink" title="链接 (Ctrl+K)">
            🔗
          </el-button>
          <el-button @click="insertImage" title="图片">
            🖼️
          </el-button>
          <el-button @click="insertCode" title="代码块">
            💻
          </el-button>
        </el-button-group>
        
        <div class="editor-info">
          <span class="word-count">{{ wordCount }} 字</span>
          <el-button 
            v-if="isModified" 
            type="primary" 
            size="small" 
            @click="saveContent"
            title="保存 (Ctrl+S)"
          >
            <el-icon><Check /></el-icon>
            保存
          </el-button>
        </div>
      </div>
    </div>
    
    <!-- 编辑器主体 -->
    <div class="editor-body" :style="{ height: editorHeight }">
      <!-- 仅编辑模式 -->
      <div v-if="activeTab === 'edit'" class="editor-only">
        <el-input
          ref="textareaRef"
          v-model="content"
          type="textarea"
          :placeholder="placeholder"
          class="markdown-textarea"
          @input="handleInput"
          @keydown="handleKeydown"
        />
      </div>
      
      <!-- 仅预览模式 -->
      <div v-else-if="activeTab === 'preview'" class="preview-only">
        <div class="markdown-preview" v-html="renderedMarkdown"></div>
      </div>
      
      <!-- 分屏模式 -->
      <div v-else class="split-view">
        <div class="split-editor">
          <div class="split-header">编辑</div>
          <el-input
            ref="splitTextareaRef"
            v-model="content"
            type="textarea"
            :placeholder="placeholder"
            class="markdown-textarea"
            @input="handleInput"
            @keydown="handleKeydown"
          />
        </div>
        
        <div class="split-divider"></div>
        
        <div class="split-preview">
          <div class="split-header">预览</div>
          <div class="markdown-preview" v-html="renderedMarkdown"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import { Check } from '@element-plus/icons-vue';
import { marked } from 'marked';
import Prism from 'prismjs';

// 导入 Prism.js 语言支持（按依赖顺序导入）
import 'prismjs/components/prism-markup-templating'; // PHP 的依赖
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-go';
import 'prismjs/components/prism-rust';
import 'prismjs/components/prism-php'; // 需要 markup-templating
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-scss';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-yaml';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-markdown';

// 导入 Prism.js 主题
import 'prismjs/themes/prism-tomorrow.css';

// Props
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: '请输入 Markdown 内容...'
  },
  height: {
    type: [String, Number],
    default: 500
  }
});

// Events
const emit = defineEmits(['update:modelValue', 'save']);

// 响应式数据
const activeTab = ref('edit');
const content = ref(props.modelValue);
const originalContent = ref(props.modelValue);
const textareaRef = ref(null);
const splitTextareaRef = ref(null);

// 计算属性
const editorHeight = computed(() => {
  return typeof props.height === 'number' ? `${props.height}px` : props.height;
});

const isModified = computed(() => {
  return content.value !== originalContent.value;
});

const wordCount = computed(() => {
  const text = content.value.replace(/[\r\n\s]/g, '');
  const chineseCount = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
  const englishCount = (text.match(/[a-zA-Z]+/g) || []).join('').length;
  return chineseCount + Math.ceil(englishCount / 4);
});

// 配置 marked 使用 Prism.js 高亮
const renderer = new marked.Renderer();

renderer.code = function(code, language) {
  if (language && Prism.languages[language]) {
    try {
      const highlightedCode = Prism.highlight(code, Prism.languages[language], language);
      return `<div class="md-code-block">
        <span class="md-language-label">${language}</span>
        <pre class="md-pre language-${language}"><code class="md-code language-${language}">${highlightedCode}</code></pre>
      </div>`;
    } catch (error) {
      console.warn(`语法高亮失败 (${language}):`, error);
      // 降级到普通代码块
      return `<div class="md-code-block">
        <span class="md-language-label">${language}</span>
        <pre class="md-pre"><code class="md-code">${code}</code></pre>
      </div>`;
    }
  }
  return `<div class="md-code-block">
    <pre class="md-pre"><code class="md-code">${code}</code></pre>
  </div>`;
};

renderer.heading = function(text, level) {
  return `<h${level} class="md-heading md-h${level}">${text}</h${level}>`;
};

renderer.paragraph = function(text) {
  return `<p class="md-paragraph">${text}</p>`;
};

renderer.list = function(body, ordered) {
  const tag = ordered ? 'ol' : 'ul';
  const className = ordered ? 'md-ordered-list' : 'md-unordered-list';
  return `<${tag} class="${className}">${body}</${tag}>`;
};

renderer.listitem = function(text) {
  return `<li class="md-list-item">${text}</li>`;
};

renderer.link = function(href, title, text) {
  const titleAttr = title ? ` title="${title}"` : '';
  const target = href.startsWith('http') ? ' target="_blank" rel="noopener noreferrer"' : '';
  return `<a class="md-link" href="${href}"${titleAttr}${target}>${text}</a>`;
};

renderer.image = function(href, title, text) {
  const titleAttr = title ? ` title="${title}"` : '';
  return `<img class="md-image" src="${href}" alt="${text}"${titleAttr} loading="lazy">`;
};

renderer.blockquote = function(quote) {
  return `<blockquote class="md-blockquote">${quote}</blockquote>`;
};

renderer.codespan = function(code) {
  return `<code class="md-inline-code">${code}</code>`;
};

marked.setOptions({
  renderer: renderer,
  breaks: true,
  gfm: true,
  tables: true,
  sanitize: false,
  highlight: function(code, lang) {
    if (lang && Prism.languages[lang]) {
      try {
        return Prism.highlight(code, Prism.languages[lang], lang);
      } catch (error) {
        console.warn(`语法高亮失败 (${lang}):`, error);
        return code;
      }
    }
    return code;
  }
});

// 渲染 Markdown
const renderedMarkdown = computed(() => {
  if (!content.value) return '<p class="empty-content">暂无内容</p>';
  
  try {
    return marked(content.value);
  } catch (error) {
    console.error('Markdown 渲染失败:', error);
    return '<p class="error-content">内容渲染失败</p>';
  }
});

// 监听 props 变化
watch(() => props.modelValue, (newValue) => {
  content.value = newValue;
  originalContent.value = newValue;
});

// 监听内容变化
watch(content, (newValue) => {
  emit('update:modelValue', newValue);
});

// 处理输入
const handleInput = () => {
  // 可以在这里添加实时保存逻辑
};

// 保存内容
const saveContent = () => {
  originalContent.value = content.value;
  emit('save', content.value);
  ElMessage.success('内容已保存');
};

// 工具栏功能
const insertBold = () => {
  insertText('**', '**', '粗体文本');
};

const insertItalic = () => {
  insertText('*', '*', '斜体文本');
};

const insertLink = () => {
  insertText('[', '](https://example.com)', '链接文本');
};

const insertImage = () => {
  insertText('![', '](https://example.com/image.jpg)', '图片描述');
};

const insertCode = () => {
  insertText('\n```javascript\n', '\n```\n', '// 代码内容');
};

// 插入文本的通用方法
const insertText = (before, after, placeholder) => {
  const textarea = getCurrentTextarea();
  if (!textarea) return;
  
  const start = textarea.selectionStart;
  const end = textarea.selectionEnd;
  const selectedText = content.value.substring(start, end) || placeholder;
  
  const newText = content.value.substring(0, start) + 
                  before + selectedText + after + 
                  content.value.substring(end);
  
  content.value = newText;
  
  nextTick(() => {
    textarea.focus();
    textarea.setSelectionRange(
      start + before.length,
      start + before.length + selectedText.length
    );
  });
};

// 获取当前活动的文本框
const getCurrentTextarea = () => {
  if (activeTab.value === 'split') {
    return splitTextareaRef.value?.$refs?.textarea;
  }
  return textareaRef.value?.$refs?.textarea;
};

// 快捷键处理
const handleKeydown = (event) => {
  if (event.ctrlKey || event.metaKey) {
    switch (event.key) {
      case 's':
        event.preventDefault();
        saveContent();
        break;
      case 'b':
        event.preventDefault();
        insertBold();
        break;
      case 'i':
        event.preventDefault();
        insertItalic();
        break;
      case 'k':
        event.preventDefault();
        insertLink();
        break;
    }
  }
};

// 全局快捷键监听
const handleGlobalKeydown = (event) => {
  if (event.ctrlKey || event.metaKey) {
    if (event.key === 's') {
      event.preventDefault();
      saveContent();
    }
  }
};

onMounted(() => {
  document.addEventListener('keydown', handleGlobalKeydown);
});

onUnmounted(() => {
  document.removeEventListener('keydown', handleGlobalKeydown);
});
</script>

<style scoped>
.unified-markdown-editor {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  background-color: #fff;
  overflow: hidden;
}

.editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  background-color: #f8f9fa;
  flex-shrink: 0;
}

.editor-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.editor-info {
  display: flex;
  gap: 12px;
  align-items: center;
}

.word-count {
  font-size: 12px;
  color: #909399;
}

.editor-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.editor-only,
.preview-only {
  height: 100%;
  flex: 1;
  overflow: hidden;
}

.markdown-textarea {
  height: 100%;
}

.markdown-textarea :deep(.el-textarea__inner) {
  height: 100% !important;
  resize: none;
  font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;
  font-size: 14px;
  line-height: 1.6;
  border: none;
  box-shadow: none;
  padding: 16px;
}

.split-view {
  display: flex;
  height: 100%;
  flex: 1;
}

.split-editor,
.split-preview {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.split-header {
  padding: 8px 16px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  font-size: 12px;
  font-weight: 500;
  color: #606266;
  flex-shrink: 0;
}

.split-divider {
  width: 1px;
  background-color: #e4e7ed;
  flex-shrink: 0;
}

.split-preview .markdown-preview {
  flex: 1;
  overflow-y: auto;
}

.markdown-preview {
  padding: 16px;
  height: 100%;
  overflow-y: auto;
  background-color: #fff;
}

.empty-content {
  color: #c0c4cc;
  font-style: italic;
  text-align: center;
  margin-top: 2em;
}

.error-content {
  color: #f56c6c;
  text-align: center;
  margin-top: 2em;
}
</style>
